package thing

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"iot-base/auth/common"
	Log "iot-base/auth/logger"
	types2 "iot-base/auth/types"
	"iot-base/auth/utils"
	_ "iot-base/common/ctrl"
	"iot-base/common/ctrltype"
	"iot-base/common/notify"
	"strings"
	"time"
)

// GetProfiles 获取配置.
func GetProfiles(c *gin.Context) {
	requestId, _ := c.Get("RequestId")
	uid := c.GetInt64("uid")
	resp := types2.NewResult(c)
	var req types2.ReqGetProfiles
	// 编号
	if err := c.ShouldBind(&req); err != nil {
		Log.Log.Errorf("[%s] [%v] err:=%v", requestId, uid, err)
		resp.ErrorCode(types2.ParamsError, "")
		return
	}
	var number string
	if strings.Contains(req.ThingId, "#") {
		ipcName := strings.Split(req.ThingId, "#")
		req.ThingId = ipcName[0]
		number = ipcName[1]
	}
	var cmd ctrltype.CtrlCmd
	cmd.ID = types2.GetProfiles
	cmd.ThingID = req.ThingId
	var pResult *ctrltype.CtrlResult
	notify.Ctrl(&cmd, 3*time.Second, func(pReply *ctrltype.CtrlResult) {
		pResult = pReply

	}, true)
	if pResult == nil {
		resp.Success(gin.H{})
		return
	}
	if pResult.Error != nil && pResult.Error.Error() == "time out" {
		Log.Log.Error("GetProfiles", "cmd", cmd, "result", pResult.Error)
		resp.Success(gin.H{})
		return
	}
	if number != "" {
		result := pResult.Result["list"].([]interface{})
		// 归类, 把同一个摄像头的码流放到一起
		ipcList := make(map[string][]map[string]interface{})
		for _, value := range result {
			mapData := value.(map[string]interface{})
			// VideoSourceToken: "VideoSource_3" 每个摄像头的都是一样的
			if v, ok := mapData["VideoSource"]; ok {
				token := v.(map[string]interface{})["token"].(string)
				serialNum := strings.Split(token, "_")[1]
				if _, ok := ipcList[serialNum]; !ok {
					ipcList[serialNum] = make([]map[string]interface{}, 0, 2)
				}
				ipcList[serialNum] = append(ipcList[serialNum], mapData)
			}
		}
		resp.Success(gin.H{"list": ipcList[number]})
		return
	} else {
		resp.Success(pResult.Result)
		return
	}

}

// SetProfile 修改配置文件.
func SetProfile(c *gin.Context) {
	requestId, _ := c.Get("RequestId")
	uid := c.GetInt64("uid")
	resp := types2.NewResult(c)
	var req types2.VideoEncoder
	if err := c.ShouldBind(&req); err != nil {
		Log.Log.Errorf("[%s] [%v] err:=%v", requestId, uid, err)
		resp.ErrorCode(types2.ParamsError, "")
		return
	}
	if strings.Contains(req.ThingId, "#") {
		ipcName := strings.Split(req.ThingId, "#")
		req.ThingId = ipcName[0]
	}
	var cmd ctrltype.CtrlCmd
	cmd.ID = types2.SetProfile
	cmd.ThingID = req.ThingId
	params, _ := utils.StructToMap(req)
	cmd.Params = params
	result, err := common.CtrlResp(&cmd)
	if result != nil && err == nil {
		resp.Success(result)
	} else {
		fmt.Println(err)
		resp.ErrorCode(types2.SetProfileErr, "")
	}
	return
}

// ContinuousMove 连续移动.
func ContinuousMove(c *gin.Context) {
	requestId, _ := c.Get("RequestId")
	uid := c.GetInt64("uid")
	resp := types2.NewResult(c)
	var req types2.ReqContinuousMove
	if err := c.ShouldBind(&req); err != nil {
		Log.Log.Errorf("[%s] [%v] err:=%v", requestId, uid, err)
		resp.ErrorCode(types2.ParamsError, "")
		return
	}

	if strings.Contains(req.ThingId, "#") {
		ipcName := strings.Split(req.ThingId, "#")
		req.ThingId = ipcName[0]
	}

	params := make(map[string]interface{})
	if req.Speed <= 0 || req.Speed > 10 {
		req.Speed = 5
	}
	// horizontal
	if req.X == "left" {
		params["X"] = -float64(req.Speed) / 10.0
	} else if req.X == "right" {

		params["X"] = float64(req.Speed) / 10.0
	}
	// vertical
	if req.Y == "up" {
		params["Y"] = float64(1) //float64(req.Speed) / 10.0
	} else if req.Y == "down" {
		params["Y"] = float64(-1) //-float64(req.Speed) / 10.0
	}
	// zoom
	params["ProfileToken"] = req.ProfileToken
	var cmd ctrltype.CtrlCmd
	// 移动焦距
	if req.Z != "" {
		cmd.ID = types2.RelativeZoomMove
		var zoom float64
		if req.Z == "big" {
			// 焦距放大
			zoom = float64(0.1)
		} else {
			// 焦距放小
			zoom = float64(-0.1)
		}
		cmd.Params = map[string]interface{}{
			"ProfileToken": req.ProfileToken,
			"Z":            zoom, // 焦距
			"Speed":        float64(req.Speed) / 10.0,
		}
	} else {
		cmd.ID = types2.ContinuousMove
		cmd.Params = params
	}
	cmd.ThingID = req.ThingId
	fmt.Println("测试移动:", cmd)
	result, err := common.CtrlResp(&cmd)
	if result != nil && err == nil {
		resp.Success(result)
	} else {
		resp.ErrorCode(types2.Fail, "")
	}
	return
}

// StopMove 停止.
func StopMove(c *gin.Context) {
	requestId, _ := c.Get("RequestId")
	uid := c.GetInt64("uid")
	resp := types2.NewResult(c)
	var req types2.ReqContinuousMove
	if err := c.ShouldBind(&req); err != nil {
		Log.Log.Errorf("[%s] [%v] err:=%v", requestId, uid, err)
		resp.ErrorCode(types2.ParamsError, "")
		return
	}

	if strings.Contains(req.ThingId, "#") {
		ipcName := strings.Split(req.ThingId, "#")
		req.ThingId = ipcName[0]
	}

	params := make(map[string]interface{})
	if req.Speed <= 0 || req.Speed > 10 {
		req.Speed = 5
	}
	// horizontal
	params["X"] = true
	// vertical
	params["Y"] = true
	params["ProfileToken"] = req.ProfileToken
	var cmd ctrltype.CtrlCmd
	cmd.ID = types2.StopMove
	cmd.ThingID = req.ThingId
	cmd.Params = params
	result, err := common.CtrlResp(&cmd)
	if result != nil && err == nil {
		resp.Success(result)
	} else {
		resp.ErrorCode(types2.Fail, "")
	}
	return
}

func FocusMove(c *gin.Context) {
	requestId, _ := c.Get("RequestId")
	uid := c.GetInt64("uid")
	resp := types2.NewResult(c)
	var req types2.ReqFocusMove
	if err := c.ShouldBind(&req); err != nil {
		Log.Log.Errorf("[%s] [%v] err:=%v", requestId, uid, err)
		resp.ErrorCode(types2.ParamsError, "")
		return
	}
	if strings.Contains(req.ThingId, "#") {
		ipcName := strings.Split(req.ThingId, "#")
		req.ThingId = ipcName[0]
	}
	params := map[string]interface{}{
		"VideoSourceToken": req.VideoSourceToken,
		"Type":             "Absolute",
		"Position":         req.Position,
		"Speed":            float64(1),
	}
	var cmd ctrltype.CtrlCmd
	cmd.ID = types2.FocusMove
	cmd.ThingID = req.ThingId
	cmd.Params = params
	result, err := common.CtrlResp(&cmd)
	if result != nil && err == nil {
		resp.Success(result)
	} else {
		Log.Log.Errorf("[%s] [%v] GotoPreset err:=%v", requestId, uid, err)
		resp.ErrorCode(types2.Fail, "")
	}
	return
}
